package edu.csl.study.springboot.redis.controller;

import edu.csl.study.springboot.redis.service.RedissonService;
import edu.csl.study.springboot.zookeeper.service.CuratorService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.log4j.Log4j2;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.concurrent.TimeUnit;

@Controller
@RequestMapping("/lock")
@Log4j2
@Api(tags = "分布式锁测试")
public class LockController {
    @Autowired
    private RedissonService redissonService;
    @Autowired
    protected CuratorService curatorService;

    @ApiOperation("Redisson分布式所测试1")
    @PostMapping("/lock1")
    @ResponseBody
    public  ResponseEntity lockDemo(){
        String serverName = "测试分布式锁";
        String lockKey = "34343434343434";
        // 公平加锁，60秒后锁自动释放
        boolean isLocked = false;
        // 如果成功获取到锁就继续执行
        //最多等待3秒；获取锁后，不管业务逻辑有没有执行完，60秒后会自动释放
        if(redissonService.tryLock(lockKey , TimeUnit.SECONDS, 3, 60)){
            log.info("获取锁成功！！");
            isLocked = true;
            try {
                // 执行业务代码操作
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                //释放锁
               redissonService.unlock(lockKey);
            }
        } else { // 未获取到锁
            log.info("获取锁失败！！");
        }
        return new ResponseEntity<>("获取锁："+isLocked,null, HttpStatus.OK);
    }
    @ApiOperation("Redisson分布式所测试2")
    @PostMapping("/lock2")
    @ResponseBody
    public ResponseEntity lock2(){

        String lockKey = "34343434343434";
        // 公平加锁，60秒后锁自动释放
        boolean isLocked = redissonService.tryLock(lockKey , TimeUnit.SECONDS, 30, 50);

        log.info("获取锁：" +isLocked);

        return new ResponseEntity<>("获取锁："+isLocked,null, HttpStatus.OK);
    }

    @ApiOperation("Redisson分布式所测试 - Watch Dog - 续期测试")
    @PostMapping("/lock3")
    @ResponseBody
    public  ResponseEntity lock3(){
        String serverName = "测试分布式锁";
        String lockKey = "34343434343434";
        RLock lock = redissonService.lock(lockKey);
        return new ResponseEntity<>("获取锁："+lock,null, HttpStatus.OK);
    }
    @ApiOperation("Redisson分布式所测试 - 超时自动释放锁")
    @PostMapping("/lock4")
    @ResponseBody
    public  ResponseEntity lock4(){
        String serverName = "测试分布式锁";
        String lockKey = "34343434343434";
        RLock lock = redissonService.lock(lockKey,300);
        return new ResponseEntity<>("获取锁："+lock,null, HttpStatus.OK);
    }
    @ApiOperation("Zookeeper分布式锁测试 - 有超时阻塞 ")
    @PostMapping("/zkLock")
    @ResponseBody
    public  ResponseEntity lock5(){
        String key ="301031723301010080440";
        InterProcessMutex mutexLock = curatorService.getlock(key);
        boolean lock = false;
        //获取成功了，那么释放
        if(curatorService.lock(mutexLock,10l)){
            try{
                lock = true;
                Thread.sleep(10000);
                log.info("获取锁成功！！");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally{
                curatorService.unLock(mutexLock);
                log.info("释放锁成功！！");
            }
        }else{
            log.info("获取锁失败！！");
        }
        return new ResponseEntity<>("获取锁："+lock,null, HttpStatus.OK);
    }
    @ApiOperation("Zookeeper分布式锁测试 - 无限阻塞，直到获取到锁 ")
    @PostMapping("/zkLock2")
    @ResponseBody
    public  ResponseEntity lock6(){
        String key ="301031723301010080440";
        InterProcessMutex mutexLock = curatorService.getlock(key);
        boolean lock = false;
        curatorService.lock(mutexLock);//未获取成功会一直阻塞
        lock = true;
        try{
            Thread.sleep(10000);
            log.info("获取锁成功！！");

        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally{
            curatorService.unLock(mutexLock);
            log.info("释放锁成功！！");
        }
        return new ResponseEntity<>("获取锁："+lock,null, HttpStatus.OK);
    }


}
